﻿namespace Payment.Albaba.PcCode
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Web;

    using Newtonsoft.Json;

    using Payment.Albaba.Com;

    /// <summary>
    /// 类名：Notify
    /// 功能：支付宝通知处理类
    /// 详细：处理支付宝各接口通知返回
    /// 版本：3.3
    /// 修改日期：2011-07-05
    /// '说明：
    /// 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
    /// 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
    /// 
    /// //////////////////////注意/////////////////////////////
    /// 调试通知返回时，可查看或改写log日志的写入TXT里的数据，来检查通知返回是否正常 
    /// </summary>
    public class AliPayNotify
    {
        /// <summary>
        /// 支付宝交易号
        /// </summary>
        public string TradeNo
        {
            get
            {
                return this.request.Form["trade_no"];
            }
        }

        /// <summary>
        /// 商户订单号
        /// </summary>
        public string OutTradeNo
        {
            get
            {
                return this.request.Form["out_trade_no"];
            }
        }

        /// <summary>
        /// 支付宝交易号
        /// </summary>
        public string TradeStatus
        {
            get
            {
                return this.request.Form["trade_status"];
            }
        }

        /// <summary>
        /// md5Sign
        /// </summary>
        public string Sign
        {
            get
            {
                return this.request.Form["sign"];
            }
        }

        /// <summary>
        /// 通知ID
        /// </summary>
        public string NotifyId
        {
            get
            {
                return this.request.Form["notify_id"];
            }
        }
         

        /// <summary>
        /// 阿里配置信息
        /// </summary>
        private AliConfig config;

     

        /// <summary>
        /// 获取http
        /// </summary>
        private HttpRequestBase request;

        /// <summary>
        /// Initializes a new instance of the <see cref="AliPayNotify"/> class. 
        /// 构造
        /// </summary>
        /// <param name="config">
        /// </param> 
        /// <param name="request">
        /// The request.
        /// </param>
        public AliPayNotify(AliConfig config , HttpRequestBase request)
        {
            this.config = config;
           
            this.request = request;
        }

        /// <summary>
        /// request数据
        /// </summary>
        /// <returns></returns>
        public string GetJson()
        {
            return JsonConvert.SerializeObject(AliCore.GetRequestPost(this.request));
        }

        /// <summary>
        /// 验证消息是否是支付宝发出的合法消息
        /// </summary>
        /// <returns>
        /// 验证结果
        /// </returns>
        public bool Verify()
        { 
            // 获取返回时的签名验证结果
            bool isSign = this.GetSignVeryfy(AliCore.GetRequestPost(this.request), this.Sign);
         
            // 获取是否是支付宝服务器发来的请求的验证结果
            string responseTxt = "true";
            if (!string.IsNullOrEmpty(this.NotifyId))
            {
                responseTxt = this.GetResponseTxt(this.NotifyId);
            }

            // 判断responsetTxt是否为true，isSign是否为true
            // responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
            // isSign不是true，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
            if (responseTxt == "true"  )
            {
                // 验证成功
                return true;
            }

            return false;
        }


        /// <summary>
        /// 获取返回时的签名验证结果
        /// </summary>
        /// <param name="inputPara">通知返回参数数组</param>
        /// <param name="sign">对比的签名结果</param>
        /// <returns>签名验证结果</returns>
        private bool GetSignVeryfy(Dictionary<string, string> inputPara, string sign)
        { 
            var sPara = new Dictionary<string, string>();

            // 过滤空值、sign与sign_type参数
            sPara = AliCore.FilterPara(inputPara);

            // 获取待签名字符串
            string preSignStr = AliCore.CreateLinkString(sPara);

            // 获得签名验证结果 
            return AliCore.Verify(preSignStr, sign, this.config.Key, this.config.InputCharset);
             
        }

        /// <summary>
        /// 获取是否是支付宝服务器发来的请求的验证结果
        /// </summary>
        /// <param name="notifyId">通知验证ID</param>
        /// <returns>验证结果</returns>
        private string GetResponseTxt(string notifyId)
        {
            string veryfyUrl = AliGateway.HttpsVeryfyUrl + "partner=" + this.config.Partner + "&notify_id=" + notifyId;

            // 获取远程服务器ATN结果，验证是否是支付宝服务器发来的请求
            var httpHelper = new WebCommon.HttpHelper();
            httpHelper.Url = veryfyUrl;
            httpHelper.Method = true;
            httpHelper.Data = string.Empty;
            return httpHelper.PostPage();
        } 
    }
}